package com.yznote.cloudesk.websocket.server;

import com.alibaba.fastjson.JSON;
import com.yznote.cloudesk.common.constants.YConstant;
import com.yznote.cloudesk.common.pojo.Message;
import com.yznote.cloudesk.common.pojo.User;
import com.yznote.cloudesk.config.JWTconfig;
import com.yznote.cloudesk.user.mapper.UserMapper;
import com.yznote.cloudesk.websocket.service.WebSocketService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.rmi.RemoteException;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;

@ServerEndpoint("/server/{token}")
@Slf4j
@Component
public class YDWebSocketSession {
    // 在線人數
    private static AtomicInteger onlineCount = new AtomicInteger();
    // 用戶會話的map
    private static ConcurrentHashMap<Long, YDWebSocketSession> webSocketMap = new ConcurrentHashMap<>();
    // 會話實例
    private Session session;
    // 會話的用戶id
    private User user;
    //
    private String userName;
    static WebSocketService webSocketService;

    @Autowired
    public void setService(WebSocketService webSocketService) {
        this.webSocketService = webSocketService;
    }

    @OnOpen
    public void sessionOpen(Session session, @PathParam("token") String token) throws IOException {
        User user = JWTconfig.verifyToken(token);
        if (user == null) {
            // 非法连接
            throw new RemoteException("非法连接");
        }
        this.user = user;
        this.session = session;
        if (!webSocketMap.contains(user.getUserId())) {
            onlineCount.incrementAndGet();
        }
        webSocketMap.put(user.getUserId(), this);
        sendMessage(YConstant.WEBSOCKET_CONNECT_SUCCESS);
    }

    @OnError
    public void onError(Session session, Throwable error) {
        if (webSocketMap.containsKey(user.getUserId())) {
            webSocketMap.remove(user.getUserId());
            onlineCount.decrementAndGet();
        }
    }

    @OnMessage
    public void onMessage(String message, Session session) {
        // 收取到消息
        Message message1 = JSON.parseObject(message, Message.class);
        message1.setCreateBy(user.getUserId());
        message1.setUpdateBy(user.getUserId());
        message1.setUserName(user.getUserName());
        webSocketService.sendMsgToRoom(message1);
    }

    @OnClose
    public void OnClose() {
        webSocketMap.remove(user.getUserId());
        onlineCount.decrementAndGet();
    }

    public Session getSession() {
        return this.session;
    }

    public static Integer getOnlineUser() {
        return onlineCount.get();
    }

    public static YDWebSocketSession getYDSession(Long userId) {
        return webSocketMap.get(userId);
    }

    public static ConcurrentHashMap<Long, YDWebSocketSession> getWebSocketMap() {
        return webSocketMap;
    }

    /**
     * 发送消息给本session对应的用户
     *
     * @param message 字符串消息
     * @throws IOException
     */
    public void sendMessage(String message) throws IOException {
        this.session.getBasicRemote().sendText(message);
    }

    /**
     * 发送消息给本session对应的用户
     *
     * @param message 消息实体
     * @throws Exception
     */
    public void sendMessage(Message message) throws Exception {
        this.session.getBasicRemote().sendText(JSON.toJSONString(message));
    }

    /**
     * 发送消息给指定用户
     *
     * @param session 指定用户会话
     * @param message 消息实体
     * @throws IOException
     */
    public static void sendMsg(YDWebSocketSession session, Message message) throws IOException {
        session.getSession().getBasicRemote().sendText(JSON.toJSONString(message));
    }

    /**
     * 发送消息给指定用户
     *
     * @param session 指定用户会话
     * @param message 字符串消息
     * @throws IOException
     */
    public static void sendMsg(YDWebSocketSession session, String message) throws IOException {
        session.getSession().getBasicRemote().sendText(message);
    }

    /**
     * 发送消息给指定用户
     *
     * @param message 字符串
     * @param userId  指定用户id
     * @throws IOException
     */
    public static void sendMsg(String message, Long userId) throws IOException {
        YDWebSocketSession ydSession = getYDSession(userId);
        if (ydSession != null) {
            ydSession.getSession().getBasicRemote().sendText(message);
        }
    }

    /**
     * 发送消息给指定用户
     *
     * @param message 消息实体
     * @param userId  指定用户id
     * @throws IOException
     */
    public static void sendMsg(Message message, Long userId) throws IOException {
        YDWebSocketSession ydSession = getYDSession(userId);
        if (ydSession != null) {
            ydSession.getSession().getBasicRemote().sendText(JSON.toJSONString(message));
        }

    }

}
